#include "socketservidor.h"

namespace red {
namespace sockets {

SocketServidor::SocketServidor(unsigned int p_wPort, unsigned int p_wMaxConnections) {

	if (!this->create()) {
	} else if ((!bind(p_wPort)) || (!listen(p_wMaxConnections))) {
		this->close();
	} else {
		this->setUtilizable(true);
	}
}

SocketServidor::~SocketServidor() {
}

SocketServidor::SocketServidor(int p_Socket) {
	this->m_Socket = p_Socket;
	this->setUtilizable(true);
}

bool SocketServidor::bind(unsigned int p_wPort) {

	int t_iRes;
    int t_iReusarPuerto = 1;
	bool t_b = false;

	if (this->isValid() && (setsockopt(this->m_Socket,
		SOL_SOCKET, SO_REUSEADDR, &t_iReusarPuerto, sizeof(int)) != -1)) {

		this->m_sockaddr_in.sin_family = AF_INET;
		this->m_sockaddr_in.sin_addr.s_addr = INADDR_ANY;
		this->m_sockaddr_in.sin_port = htons(p_wPort);

		t_iRes = ::bind(this->m_Socket, reinterpret_cast<sockaddr *>(&this->m_sockaddr_in),
			sizeof(this->m_sockaddr_in));

		if (t_iRes != -1) {
			t_b = true;
		}
	}

	return t_b;
}

bool SocketServidor::listen(unsigned int p_wMaxConnections) {

	int t_iRes;
	bool t_b = false;

	if (this->isValid()) {

		t_iRes = ::listen(this->m_Socket, p_wMaxConnections);

		if (t_iRes != -1) {
			t_b = true;
		}
    }

	return t_b;
}

SocketServidor *SocketServidor::accept() {

	socklen_t t_socklen_t = sizeof(this->m_sockaddr_in);
	int t_Socket;
	SocketServidor *t_pSocketServidor = NULL;

	t_Socket = ::accept(this->m_Socket, reinterpret_cast<sockaddr *>(&this->m_sockaddr_in), 
		&t_socklen_t);
	
	if (t_Socket != -1) {
		t_pSocketServidor = new SocketServidor(t_Socket);
	}

	return t_pSocketServidor;
}

}
}
